<template>
  <el-card class="box-card">
    <div class="page-container">
      <div class="page-header">广告配置</div>
      <div class="page-tags">
        <div class="page_left">
          <li
            class="page_item"
            :class="current == item.module ? 'active' : ''"
            v-for="item in tabList"
            :key="item.module"
            @click="handleTabClick(item)"
          >
            {{ item.name }}
          </li>
        </div>
        <div class="page_right">
          <ul class="page_list">
            <el-button
              class="newBanner"
              size="large"
              v-hasPermi="['showManage:newbuilt:created']"
              @click="newBanner"
              >新建Banner</el-button
            >
            <el-button
              class="officially"
              size="large"
              @click="officiallyBtn"
              v-hasPermi="['showManage:library:Officia']"
              type="primary"
              >素材库</el-button
            >
          </ul>
        </div>
      </div>
    </div>

    <div class="banner-container">
      <!-- 线上banner -->
      <div class="online-banner-box">
        <div class="title">线上Banner</div>
        <div class="banner-list">
          <!-- 渲染目标div -->
          <div
            class="banner-item"
            v-for="(item, index) in displayData"
            :key="index"
            :id="`target-${index + 1}`"
            :data-index="index + 1"
            :class="{
              'has-img': item.img_url,
              highlight: highlightedDiv === index + 1,
            }"
            @dragenter="onDragEnter(index + 1)"
            @dragleave="onDragLeave"
            @dragover.prevent
            @drop="() => onDrop(index + 1, item)"
            draggable="true"
            @dragstart="() => onDragStart(item.id, 'internal')"
          >
            <div
              class="img-box"
              :style="{
                background: `url(${item.img_url}) 35% center / cover no-repeat`,
              }"
            >
              <div
                class="banner-hover"
                v-if="hasContent(item)"
                :style="{ cursor: hasContent(item) ? 'pointer' : 'auto' }"
              >
                <div
                  class="online-banner-cover"
                  style="height: 100; display: flex"
                >
                  <div class="icon">
                    <Rank style="width: 1em; height: 1em; margin-right: 8px" />
                  </div>
                  <div class="icon" @click="editBtn(item)">
                    <EditPen
                      style="width: 1em; height: 1em; margin-right: 8px"
                    />
                  </div>
                  <div class="icon" @click="handlePreview(item)">
                    <ZoomIn
                      style="width: 1em; height: 1em; margin-right: 8px"
                    />
                  </div>
                  <div class="icon" @click="deteleBtn(item)">
                    <Delete
                      style="width: 1em; height: 1em; margin-right: 8px"
                    />
                  </div>
                </div>
              </div>
            </div>
            <div class="number">{{ index + 1 }}</div>
          </div>
        </div>
      </div>
      <!-- 线下banner-我的banner -->
      <div class="off-banner-box">
        <div class="title">我的Banner</div>
        <div v-if="offlineData.length">
          <el-input
            :prefix-icon="Search"
            v-model="keywords"
            placeholder="请输入素材名称"
            style="width: 320px"
            clearable
          >
            <template #append>
              <span class="search" @click="handleSearch">搜索</span>
            </template>
          </el-input>
          <div class="off-banner-list" :class="{ isMob: current == 2 }">
            <div
              class="banner-item"
              v-for="(item, index) in offlineData"
              :key="index"
              :id="`draggable-${item.id}`"
            >
              <div
                class="off-banner-bg"
                :style="{
                  background: ` url(${item.img_url}) 35% center / cover no-repeat`,
                }"
              >
                <div
                  class="banner-hover"
                  draggable="true"
                  @dragstart="() => onDragStart(item.id, 'external', item)"
                >
                  <div class="online-banner-cover" style="display: flex">
                    <div class="icon">
                      <Rank
                        style="width: 1em; height: 1em; margin-right: 8px"
                      />
                    </div>
                    <div class="icon" @click="editBtn(item)">
                      <EditPen
                        style="width: 1em; height: 1em; margin-right: 8px"
                      />
                    </div>
                    <div class="icon" @click="handlePreview(item)">
                      <ZoomIn
                        style="width: 1em; height: 1em; margin-right: 8px"
                      />
                    </div>
                    <div class="icon" @click="deteleBtn(item)">
                      <Delete
                        style="width: 1em; height: 1em; margin-right: 8px"
                      />
                    </div>
                  </div>
                </div>
              </div>
              <div class="text">{{ item.name }}</div>
            </div>
          </div>
        </div>
        <div v-else>
          <el-empty description="暂无Banner" />
        </div>
      </div>
    </div>

    <!-- 图片预览组件 -->
    <el-image-viewer
      v-if="showPreview"
      :url-list="previewImageList"
      @close="closePreview"
    />

    <!-- 弹出框 -->
    <div class="dialog">
      <el-dialog
        v-model="centerDialogVisible"
        title="Banner替换"
        width="560"
        :center="true"
        :show-close="false"
      >
        <div class="flex-box">
          <img
            class="img"
            :src="afterPic.img_url"
            style="width: 180px; height: 54px"
          />
          <div class="middle">
            <div>
              <img
                src="https://b.youzy.cn/static/img/arrow-right.441465cb.svg"
              />
            </div>
            <p>替换为</p>
          </div>
          <img
            class="img"
            v-if="beforePic.img_url"
            :src="beforePic.img_url"
            style="width: 180px; height: 54px"
          />
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button class="canle" @click="centerDialogVisible = false"
              >取消</el-button
            >
            <el-button class="sureBtn" type="primary" @click="maskBtn"
              >确定</el-button
            >
          </span>
        </template>
      </el-dialog>
    </div>
  </el-card>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { ElMessageBox } from 'element-plus';
import { useRouter, useRoute } from 'vue-router';
import { Search } from '@element-plus/icons-vue';
import { hasContent } from '@/utils';
// banner模块接口和数据
import banner from '@/modules';
const { bannerListApi, detaleApi, replaceBannerApi } = banner;
// 路由
const router = useRouter();

const route = useRoute();
// 搜索
const keywords = ref('');

const showPreview = ref(false);

const previewImageList = ref([]);

const centerDialogVisible = ref(false);

const params = ref({});

//替换前
const beforePic = ref([]);
//替换后
const afterPic = ref([]);
// 选项卡数据
const tabList = ref([
  {
    module: 1,
    name: '电脑端',
  },
  // {
  //   module: 2,
  //   name: '移动端',
  // },
]);
// 选项卡
const current = ref(1);
// 线上banner
const onlineData = ref([]);
// 线下banner
const offlineData = ref([]);
// 存储当前被高亮的目标div索引
// let highlightedDiv = ref(null);
// 选项卡切换
const handleTabClick = (item) => {
  current.value = item.module;
  keywords.value = '';
  fetchAllBanners();
};

// 新建banner
const newBanner = () => {
  router.push({
    path: 'newbuilt',
    query: { id: JSON.stringify(current.value) },
  });
};
// 官方素材
const officiallyBtn = () => {
  router.push({ path: 'library' });
};
// 使用 Promise.all 并行请求
const fetchAllBanners = async () => {
  try {
    // 获取 storeId 并缓存，避免重复获取
    const storeId =
      JSON.parse(localStorage.getItem('userDateInfo'))?.storeId || '';
    // 公共参数
    const commonParams = {
      // 机构id
      storeId,
      page: 1,
      pageSize: 5,
      type: '1',
      module: current.value,
    };

    const [onlineBanners, offlineBanners] = await Promise.all([
      // 请求线上状态的数据
      bannerListApi({ ...commonParams, status: 1 }),
      // 请求线下状态的数据，覆盖 pageSize
      bannerListApi({
        ...commonParams,
        pageSize: 1000,
        status: 0,
        search: keywords.value,
      }),
    ]);
    // 线上banner
    onlineData.value = onlineBanners.data.data;
    // 线下banner
    offlineData.value = offlineBanners.data.data;
    // 合并两个请求的结果
    const allBanners = [
      ...onlineBanners.data.data,
      ...offlineBanners.data.data,
    ];
    return allBanners;
  } catch (error) {
    console.error('error:', error);
  }
};

// 计算属性：确保数据长度至少为 5，如果不够用空对象补齐
const displayData = computed(() => {
  const minimumLength = 5;

  // 初始化一个包含 5 个空对象的数组，index + 1 就是 sort 值
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  let sortedData = Array.from({ length: minimumLength }, (_, i) => ({}));

  // 将在线数据按 sort 值填充到相应的位置
  onlineData.value.forEach((item) => {
    if (item.sort && item.sort <= minimumLength) {
      sortedData[item.sort - 1] = item; // sort 为 1 时填充到第 0 位
    }
  });

  return sortedData;
});

// 搜索
const handleSearch = () => {
  fetchAllBanners();
};
// 获取pc线上线下banner列表
fetchAllBanners();

const editBtn = (row) => {
  router.push({
    path: 'edit',
    query: { id: row.id, type: row.type, category: current.value },
  });
};

const closePreview = () => {
  previewImageList.value = [];
  showPreview.value = false;
};
// 预览图片
const handlePreview = (row) => {
  previewImageList.value.push(row.img_url);
  showPreview.value = true;
};
//删除图片
const deteleBtn = (row) => {
  try {
    const storeId =
      JSON.parse(localStorage.getItem('userDateInfo'))?.storeId || '';
    const id = row.id;
    ElMessageBox.confirm('确认删除Banner？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
      .then(async () => {
        await detaleApi({ storeId: storeId, id: id });
        await fetchAllBanners();
      })
      .catch(() => {});
  } catch (error) {
    console.log('error:', error);
  }
};

// 模拟目标div，初始化为空
let currentDraggedItem = ref(null); // 存储当前被拖拽的元素的 id
let dragOrigin = ref(''); // 存储拖拽元素的来源（external 或 internal）
let highlightedDiv = ref(null); // 存储当前被高亮的目标div索引

// 处理 dragstart 事件，保存被拖拽的元素
const onDragStart = (id, origin, item) => {
  currentDraggedItem.value = id;
  dragOrigin.value = origin;
  afterPic.value = item ? item : '';
};

const onDragEnter = (index) => {
  highlightedDiv.value = index;
};

const onDragLeave = (event) => {
  if (
    !event.relatedTarget ||
    !event.currentTarget.contains(event.relatedTarget)
  ) {
    highlightedDiv.value = null;
  }
};

// 处理 drop 事件，目标div索引作为参数
const onDrop = (targetIndex, item) => {
  const draggedId = currentDraggedItem.value;
  const origin = dragOrigin.value;
  const targetDiv = onlineData.value[targetIndex - 1];
  highlightedDiv.value = null; // 移除高亮
  const isInternal = origin === 'internal';
  const isExternal = origin === 'external';
  if (isInternal && !draggedId) return; // 如果是内部拖拽且没有拖拽元素，则不执行任何操作
  // targetDiv 是否有内容
  const hasTargetDivContent = hasContent(targetDiv);
  // item 是否有内容
  const hasItemContent = hasContent(item);
  // && !isEmpty(item)
  // 根据是否存在 targetDiv 和是否为内部或外部拖拽来确定参数
  // 根据是否存在 targetDiv 和是否为内部或外部拖拽来确定参数
  const draggedFlag =
    isExternal && hasTargetDivContent && hasItemContent ? 'dragged' : undefined;
  if (item.id == draggedId) return;
  updateBackend(draggedId, targetIndex, isInternal, item, draggedFlag); // 通知后端

  // 清空拖拽状态
  currentDraggedItem.value = null;
  dragOrigin.value = '';
};
// 后端接口请求
const updateBackend = async (id, targetIndex, isSlot, item, type = '') => {
  // 设置请求参数
  params.value = {
    id: item.id || '',
    sort: targetIndex,
    isSlot,
    changeId: id,
  };
  beforePic.value = item;

  // 如果类型不是 'dragged'，则执行位置替换
  if (type !== 'dragged') {
    await positionElement();
  }

  // 控制对话框显示与否
  centerDialogVisible.value = type === 'dragged';
};

// 替换元素位置
const positionElement = async () => {
  try {
    await replaceBannerApi(params.value);
    fetchAllBanners();
  } catch (error) {
    console.log('error:', error);
  }
};

const maskBtn = () => {
  positionElement();
  centerDialogVisible.value = false;
};

onMounted(() => {
  current.value = route.query.category ? route.query.category : 1;
});
</script>
<style lang="scss" scoped>
:deep(.el-dialog) {
  padding: 20px 0 20px 0 !important;
}
:deep(.el-dialog__header) {
  height: 40px !important;
  min-height: 40px !important;
  display: block !important;
  // border: none !important;
}
:deep(.el-dialog__footer) {
  border: none !important;
}
.page-header {
  font-size: 20px;
  font-weight: 600;
  color: #1d2129;
}
.sureBtn {
  background: #165dff;
}
.canle:hover {
  color: #165dff;
  border: 1px solid #165dff;
}
.newBanner:hover {
  border: 1px solid #165dff;
  color: #165dff;
}
.officially {
  background: #165dff;
}
// .officially:hover {
//   background: #457dff;
// }
.flex-box {
  display: flex;
  align-items: center;
  margin-top: 10px;
  margin: 10px 20px 0 20px;
  justify-content: center;
  .middle {
    margin: 25px;
    flex-wrap: wrap;
    text-align: center;
  }
  .img {
    box-shadow: 0 4px 10px 0 rgba(0, 44, 190, 0.3);
    border-radius: 10px 10px 10px 10px;
    opacity: 1;
    border: 1px solid #fff;
  }
}
.box-card {
  margin: 20px;
  height: 100%;

  .page-container {
    margin-bottom: 30px;
  }

  .card-header {
    font-size: 20px;
    font-weight: 600;
    color: #1d2129;
    padding: 10px;
  }

  .page-tags {
    color: #1d2129;
    font-size: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 60px;
    margin-top: 10px;
    border-top: 1px solid #f0f0f0;
    border-bottom: 1px solid #f0f0f0;

    .page_left {
      display: flex;

      .page_item {
        margin-right: 50px;
        cursor: pointer;
        margin-top: 15px;
        // transition: 2s linear;
      }

      .page_item:hover {
        color: #4080ff;
      }

      .page_item.active {
        font-weight: 700;
        padding-bottom: 15px;
        border-bottom: 4px solid #000;
      }

      .page_item.active:hover {
        color: #4080ff;
      }
    }
  }
}

.banner-container {
  display: inline-flex;
  flex-direction: column;
  width: 100%;

  .online-banner-box {
    padding: 16px 20px;
    padding-bottom: 47px;
    border-radius: 8px;
    background: linear-gradient(180deg, #ecf2ff, rgba(236, 242, 255, 0));

    .title {
      color: #3d3d3d;
      font-size: 14px;
      font-weight: 500;
      line-height: 14px;
      margin-bottom: 16px;
    }

    .banner-list {
      display: flex;
      gap: 20px;
      justify-content: space-between;

      .banner-item {
        position: relative;
        width: 20%;
        max-height: 92px;
        min-height: 70px;
        border: 3px dashed #c9cdd4;
        border-radius: 7px;

        &.has-img {
          border: 3px solid #fff;
          box-shadow: 0 4px 10px 0 rgba(0, 44, 190, 0.3);
          transform: translate(0);
        }

        .img-box {
          width: 100%;
          height: 100%;

          .banner-hover {
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 999;
            //;
            background: rgba(0, 0, 0, 0.65);
            // display: none;
            opacity: 0;
          }

          &:hover .banner-hover {
            opacity: 1;
            position: relative;
            z-index: 99999;
            .online-banner-cover {
              display: flex;
              justify-content: center;
              align-items: center;
              height: 100%;
              .icon {
                width: 14px;
                height: 14px;
                color: #fff;
                margin: 0 10px;
                font-size: 16px;
                font-style: normal;
                font-weight: bold;
              }
            }
          }
        }

        .number {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 19px;
          height: 19px;
          background: #bedaff;
          color: #fff;
          border-radius: 50%;
          margin: 0 auto;
          margin-top: 12px;
        }
      }
    }
  }

  .off-banner-box {
    .title {
      color: #3d3d3d;
      font-size: 14px;
      font-weight: 500;
      line-height: 14px;
      margin-bottom: 16px;
      margin-left: 20px;
    }

    :deep(.el-input-group__append) {
      border: 1px solid #165dff !important;
      background: #165dff !important;
      color: #fff;
      cursor: pointer;
      padding: 0 !important;
      box-shadow: none !important;

      &:hover {
        background: #4080ff !important;
      }
    }

    .off-banner-list {
      display: grid;
      gap: 18px;
      margin-top: 20px;
      grid-template-columns: repeat(6, 1fr);

      &.isMob {
        grid-template-columns: repeat(8, 1fr);
        gap: 16px;
      }

      .banner-item {
        background: #f7f8fa;
        overflow: hidden;
        display: inline-block;
        .off-banner-bg {
          border-top-left-radius: 4px;
          border-top-right-radius: 4px;
          min-height: 60px;
          position: relative;

          .banner-hover {
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 10;
            background: rgba(0, 0, 0, 0.65);
            // display: none;
            opacity: 0;
          }

          &:hover .banner-hover {
            opacity: 1;
            cursor: pointer;
            .online-banner-cover {
              display: flex;
              justify-content: center;
              align-items: center;
              height: 100%;
              .icon {
                width: 14px;
                height: 14px;
                color: #fff;
                margin: 0 10px;
              }
            }
          }
        }

        .text {
          height: 34px;
          line-height: 34px;
          font-size: 12px;
          white-space: nowrap;
          color: #1d2129;
          overflow: hidden;
          text-align: left;
          text-overflow: ellipsis;
          background: #f7f8fa;
          padding: 0 11px;
          cursor: pointer;
        }
      }
    }
  }
}
.banner-item {
  transition: border 0.3s;
}

.banner-item.highlight {
  border: 3px solid #409eff !important;
}
#draggable-elements {
  padding: 10px;
  border: 1px solid #ccc;
  margin-bottom: 20px;
}

// .off-banner-bg > .banner-hover {
//   &::after {
//     content: '';
//     display: inline-block;
//     width: 100%;
//     margin-bottom: 29.84%;
//   }
// }
</style>
